package jpb.hotspot;

import jpb.CommandArg;
import jpb.CoreJvmArgs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.List;

import static jpb.Assert.notNull;

/**
 * {@link jpb.JvmArg} implementation for Hotspot supporting the JVM's class path in form of list of files.
 *
 * @see jpb.JvmArg
 * @see jpb.Jvm#classPathArg()
 * @author Dariusz Kordonski
 */
final class ClassPathArg extends CoreJvmArgs.AbstractClassPathArg {

    private static final Logger logger = LoggerFactory.getLogger(ClassPathArg.class);

    private static final String CLASS_PATH_PREFIX = "-cp";
    private static final int AVG_CLASS_PATH_ELEM_LENGTH = 30;
    

    ClassPathArg() {
        super(HotspotJvm.class);
    }

    @Override
    protected void validate(List<File> classPath) {
        // this won't necessarily bring JVM down, so throwing exception might be too much
        for (File classPathElem : notNull("classPath", classPath)) {
            if (!classPathElem.exists()) {
                logger.warn("Class path element <" + classPathElem.getAbsolutePath() + "> does not exist in the file system");
            }
        }
    }

    /**
     * Creates a class path string by combining prefix '-cp ' with list
     * of absolute paths of provided files separated by platform-specific
     * path separator.
     *
     * @see File#pathSeparatorChar
     *
     * @param {@inheritDoc}
     * @return {@inheritDoc}
     */
    @Override
    protected CommandArg convert(List<File> classPath) {
        if (notNull("classPath", classPath).isEmpty()) {
            return CommandArg.empty();
        }
        StringBuilder sb = new StringBuilder(classPath.size() * AVG_CLASS_PATH_ELEM_LENGTH);
        appendFirst(classPath, sb);
        appendRest(classPath, sb);
        return CommandArg.of(CLASS_PATH_PREFIX, sb.toString());
    }


    private void appendFirst(List<File> cp, StringBuilder sb) {
        sb.append(cp.get(0).getAbsolutePath());
    }
    private void appendRest(List<File> cp, StringBuilder sb) {
        if (cp.size() == 1) {
            return;
        }
        for (File pathElem : cp.subList(1, cp.size())) {
            sb.append(File.pathSeparatorChar).append(pathElem.getAbsolutePath());
        }
    }
}
